﻿using SKeeper.Application.ViewModels.Warehouse;
using SKeeper.Domain.Repositories;
using SKeeper.Persistence.Facade;
using SKeeper.Persistence.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SKeeper.Application.InputModels;

namespace SKeeper.Application.Services.Warehouse
{
    public class WarehouseControllerService : IWarehouseControllerService
    {
        private DomainModelFacade db;
        private IStoredItemRepository storedItemsRepository;
        private IWarehouseRepository warehouseRepository;
        private ICompanyRepository companyRepository;
        private IStoredItemMovementRepository itemMovementRepository;

        public WarehouseControllerService(DomainModelFacade context)
        {
            this.db = context;
            this.storedItemsRepository = new StoredItemRepository(this.db);
            this.warehouseRepository = new WarehouseRepository(this.db);
            this.companyRepository = new CompanyRepository(this.db);
            this.itemMovementRepository = new StoredItemMovementRepository(this.db);

        }


        public void Add(CreateWarehouseViewModel model)
        {
            var usersCompany = this.companyRepository.GetAll().FirstOrDefault(x => x.UserId == model.UserId);

            this.warehouseRepository.Create(new Domain.Warehouse.Warehouse
            {
                Name = model.Name,
                CompanyId = usersCompany.Id
            });
        }

        public WarehouseIndexViewModel GetWarehouseIndexViewModel(string userId, int selectedId = 0)
        {
            var warehousesList = this.warehouseRepository.GetIncluding(x => x.Company)
                .Where(x => x.Company.UserId == userId)
                .ToList();

            var companyId = this.companyRepository.GetAll().First(x => x.UserId == userId).Id;

            if (warehousesList.Count == 0)
            {
                return new WarehouseIndexViewModel
                {
                    Selected = new WarehouseViewModel(),
                    Warehouses = new List<WarehouseViewModel>(),
                    CompanyId = companyId
                };
            }

            var warehouses = warehousesList.Select(x => new WarehouseViewModel { Id = x.Id, Name = x.Name });
            WarehouseViewModel selected = new WarehouseViewModel();

            if (selectedId == 0)
            {
                selected.Id = warehouses.First().Id;
            }

            var selectedWarehouseItems = this.storedItemsRepository
                .GetIncluding(x => x.Item).Where(x => x.WarehouseId == selected.Id)
                .ToList()
                .Select(x => new StoredItemViewModel { Name = x.Item.Name, Quantity = x.Quantity, Tax = x.Item.Tax, Unit = x.Unit });
            selected.StoredItems = selectedWarehouseItems;


            return new WarehouseIndexViewModel
            {
                Selected = selected,
                Warehouses = warehouses,
                CompanyId = companyId
            };

        }

        public WarehouseViewModel PreviewWarehouse(int id)
        {
            return new WarehouseViewModel
            {
                StoredItems = this.storedItemsRepository
                .GetAll()
                .ToList()
                .Select(x => new StoredItemViewModel { Name = x.Item.Name, Quantity = x.Quantity, Unit = x.Unit, Tax = x.Item.Tax })
            };
        }

        public ProductListViewModel GetProductList(ProductsFilterInputModel filter)
        {
            var items = new List<ProductViewModel>();

            var querry = this.itemMovementRepository
                .GetIncluding(
                    x => x.StoredItem, 
                    x => x.StoredItem.Item, 
                    x => x.Invoice,
                    x => x.Invoice.Warehouse)
            .Where(x => x.Invoice.Warehouse.CompanyId == filter.CompanyId);

            if (filter.WarehouseId != 0)
            {
                querry = querry.Where(x => x.Invoice.WarehouseId == filter.WarehouseId);
            }

            if(filter.Date.ToShortDateString() != DateTime.Now.ToShortDateString())
            {
                querry = querry.Where(x => x.Invoice.CreationDate < filter.Date);
            }

            var itemsMovement = querry.ToList();

            var storedItems = new Dictionary<int, Domain.Warehouse.StoredItem>();

            foreach(var item in itemsMovement)
            {
                if(!storedItems.ContainsKey(item.StoredItem.Id))
                {
                    storedItems.Add(item.StoredItem.Id, new Domain.Warehouse.StoredItem { Unit = item.StoredItem.Unit, Item = item.StoredItem.Item, Quantity = item.Quantity });
                }
                else
                {
                    storedItems[item.StoredItem.Id].Quantity += item.Quantity;
                }
            }

            items = storedItems.Select(x => x.Value).Select(x => new ProductViewModel(x)).ToList();
            return new ProductListViewModel { Products = items };
        }
    }
}
